package services

import (
	"errors"
	"fmt"

	"gorm.io/gorm"

	"chat-app/internal/app/models"
)

type FriendService interface {
	// 发送好友请求
	SendRequest(requesterID, targetID uint) error
	// 获取用户的好友请求列表（分页）
	GetPendingRequests(userID uint, page, pageSize int) ([]*models.FriendRequest, error)
	// 处理好友请求（接受或拒绝）
	RespondToRequest(requestID, responderID uint, accept bool) error
	// 获取用户的好友列表（分页）
	GetFriendList(userID uint, page, pageSize int) ([]*models.User, error)
	// 移除好友关系
	RemoveFriend(userID, friendID uint) error
	// 检查是否为好友
	AreFriends(userID1, userID2 uint) (bool, error)
}

type friendService struct {
	db *gorm.DB
}

func NewFriendService(db *gorm.DB) FriendService {
	return &friendService{db: db}
}

func (s *friendService) SendRequest(requesterID, targetID uint) error {
	if requesterID == targetID {
		return errors.New("cannot send friend request to yourself")
	}

	// 检查是否已经是好友
	areFriends, err := s.AreFriends(requesterID, targetID)
	if err != nil {
		return err
	}
	if areFriends {
		return errors.New("you are already friends")
	}

	// 检查是否已存在待处理的请求
	var existing models.FriendRequest
	if err := s.db.Where("requester_id = ? AND requestee_id = ?", requesterID, targetID).
		Or("requester_id = ? AND requestee_id = ? AND status = 'pending'", targetID, requesterID).
		First(&existing).Error; err == nil {
		return errors.New("friend request already exists")
	}

	// 创建新的好友请求
	request := models.FriendRequest{
		RequesterID: requesterID,
		RequesteeID: targetID,
		Status:      models.RequestStatusPending,
	}

	return s.db.Create(&request).Error
}

func (s *friendService) GetPendingRequests(userID uint, page, pageSize int) ([]*models.FriendRequest, error) {
	if page < 1 {
		page = 1
	}
	if pageSize < 1 {
		pageSize = 10
	}
	offset := (page - 1) * pageSize

	var requests []*models.FriendRequest
	err := s.db.Where("requestee_id = ? AND status = ?", userID, models.RequestStatusPending).
		Offset(offset).Limit(pageSize).
		Order("created_at DESC").
		Find(&requests).Error

	return requests, err
}

func (s *friendService) RespondToRequest(requestID, responderID uint, accept bool) error {
	// 开始事务
	tx := s.db.Begin()
	defer func() {
		if r := recover(); r != nil {
			tx.Rollback()
		}
	}()

	// 找到待处理的好友请求
	var request models.FriendRequest
	if err := tx.Where("id = ? AND status = ?", requestID, models.RequestStatusPending).
		First(&request).Error; err != nil {
		tx.Rollback()
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return errors.New("friend request not found or already processed")
		}
		return err
	}

	// 确保处理者是请求接收方
	if request.RequesteeID != responderID {
		tx.Rollback()
		return errors.New("unauthorized to respond to this request")
	}

	// 更新请求状态
	if accept {
		request.Status = models.RequestStatusAccepted
	} else {
		request.Status = models.RequestStatusRejected
	}

	if err := tx.Save(&request).Error; err != nil {
		tx.Rollback()
		return err
	}

	// 如果接受请求，创建好友关系（双向）
	if accept {
		if err := createFriendship(tx, request.RequesterID, request.RequesteeID); err != nil {
			tx.Rollback()
			return err
		}
	}

	return tx.Commit().Error
}

func createFriendship(tx *gorm.DB, userID1, userID2 uint) error {
	// 创建两条好友关系记录（双向）
	friendships := []models.Friend{
		{UserID: userID1, FriendID: userID2},
		{UserID: userID2, FriendID: userID1},
	}

	for _, f := range friendships {
		if err := tx.Create(&f).Error; err != nil {
			return fmt.Errorf("failed to create friendship: %w", err)
		}
	}
	return nil
}

func (s *friendService) GetFriendList(userID uint, page, pageSize int) ([]*models.User, error) {
	if page < 1 {
		page = 1
	}
	if pageSize < 1 {
		pageSize = 20
	}
	offset := (page - 1) * pageSize

	var friends []*models.User
	err := s.db.Table("users u").
		Select("u.id, u.phone, u.nickname").
		Joins("JOIN friends f ON u.id = f.friend_id").
		Where("f.user_id = ?", userID).
		Offset(offset).Limit(pageSize).
		Order("u.nickname ASC").
		Find(&friends).Error

	return friends, err
}

func (s *friendService) RemoveFriend(userID, friendID uint) error {
	// 开始事务
	tx := s.db.Begin()
	defer func() {
		if r := recover(); r != nil {
			tx.Rollback()
		}
	}()

	// 删除双向好友关系
	if err := tx.Where("(user_id = ? AND friend_id = ?) OR (user_id = ? AND friend_id = ?)",
		userID, friendID, friendID, userID).
		Delete(&models.Friend{}).Error; err != nil {
		tx.Rollback()
		return fmt.Errorf("failed to remove friendship: %w", err)
	}

	// 删除相关的好友请求记录
	if err := tx.Where("((requester_id = ? AND requestee_id = ?) OR (requester_id = ? AND requestee_id = ?)) AND status = ?",
		userID, friendID, friendID, userID, models.RequestStatusAccepted).
		Delete(&models.FriendRequest{}).Error; err != nil {
		tx.Rollback()
		return fmt.Errorf("failed to clean friend requests: %w", err)
	}

	return tx.Commit().Error
}

func (s *friendService) AreFriends(userID1, userID2 uint) (bool, error) {
	if userID1 == userID2 {
		return false, nil
	}

	var count int64
	err := s.db.Model(&models.Friend{}).
		Where("user_id = ? AND friend_id = ?", userID1, userID2).
		Count(&count).Error

	return count > 0, err
}
